﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

&НаКлиенте
Перем ПроверкаПрограммВыполнялась;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Элементы.ОткрытьМашиночитаемыеДоверенности.Видимость = Ложь;
	
	// Локализация
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности") Тогда
		МодульМашиночитаемыеДоверенностиФНССлужебный = ОбщегоНазначения.ОбщийМодуль("МашиночитаемыеДоверенностиФНССлужебный");
		МодульМашиночитаемыеДоверенностиФНССлужебный.ПриСозданииНаСервере(ЭтотОбъект);
	КонецЕсли;
	
	// Конец Локализация
	
	ЭлектроннаяПодписьСлужебный.УстановитьВидимостьСсылкиНаИнструкциюПоРаботеСПрограммами(Элементы.Инструкция);
	
	УстановитьУсловноеОформление();
	ЭлектроннаяПодписьСлужебный.УстановитьУсловноеОформлениеСпискаСертификатов(Сертификаты, Истина);
	
	НавигационнаяСсылка = "e1cib/app/ОбщаяФорма.НастройкиЭлектроннойПодписиИШифрования";
	
	Если Не ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
		Элементы.СтраницаНастройки.Видимость = Ложь;
		БезПраваСохранениеДанныхПользователя = Истина;
	КонецЕсли;
	
	ЭтоПолноправныйПользователь = Пользователи.ЭтоПолноправныйПользователь();
	
	Если Параметры.Свойство("ПоказатьСтраницуСертификаты") Тогда
		Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаСертификаты;
		
	ИначеЕсли Параметры.Свойство("ПоказатьСтраницуНастройки") Тогда
		Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаНастройки;
		
	ИначеЕсли Параметры.Свойство("ПоказатьСтраницуПрограммы") Тогда
		Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаПрограммы;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Параметры.СертификатыПоказать) Тогда
		СертификатыПоказать = Параметры.СертификатыПоказать;
	ИначеЕсли ЭтоПолноправныйПользователь Тогда
		СертификатыПоказать = "ВсеСертификаты";
	Иначе
		СертификатыПоказать = "МоиСертификаты";
	КонецЕсли;
		
	Если Не ЭтоПолноправныйПользователь ИЛИ СертификатыПоказать <> "ВсеСертификаты" Тогда
		ПользовательОтбор = Пользователи.ТекущийПользователь();
	КонецЕсли;
	
	// Страница Программы
	Если Не ПравоДоступа("Изменение", Метаданные.Справочники.ПрограммыЭлектроннойПодписиИШифрования) Тогда
		Элементы.Программы.ИзменятьСоставСтрок = Ложь;
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ПрограммыДобавить", "Видимость", Ложь);
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ПрограммыИзменить", "Видимость", Ложь);
		
		Элементы.ПрограммыУстановитьПометкуУдаления.Видимость = Ложь;
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ПрограммыКонтекстноеМенюДобавить", "Видимость", Ложь);
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ПрограммыКонтекстноеМенюИзменить", "Видимость", Ложь);
		
		Элементы.ПрограммыКонтекстноеМенюПрограммыУстановитьПометкуУдаления.Видимость = Ложь;
		Элементы.Программы.Заголовок =
			НСтр("ru = 'Список программ, предусмотренных администратором, которые можно использовать на компьютере'");
	КонецЕсли;
	
	// Страница Сертификаты
	
	ТекстЗапроса = Сертификаты.ТекстЗапроса;
	ЗаявлениеНаВыпускСертификатаДоступно = ЭлектроннаяПодпись.ОбщиеНастройки().ЗаявлениеНаВыпускСертификатаДоступно;
	
	Если ЗаявлениеНаВыпускСертификатаДоступно Тогда
		
		МодульЗаявлениеНаВыпускНовогоКвалифицированногоСертификата = ОбщегоНазначения.ОбщийМодуль("Обработки.ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата");
		МодульЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.ЗаполнитьСписокВыбораСостоянияЗаявления(Элементы.СертификатыПоказатьЗаявления.СписокВыбора);
		МодульЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.ДополнитьЗапросСостояниемВСпискеСертификатов(ТекстЗапроса);
		МодульЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.ДобавитьЛегенду(ЭтотОбъект, Элементы.ГруппаЛегенда);
		Элементы.СертификатыПоказать.СписокВыбора.Добавить("МоиЗаявленияВРаботе", НСтр("ru = 'Мои заявления в работе'"));
		СостоянияЗаявленияНеВРаботе = МодульЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.СостоянияЗаявленияНеВРаботе();
		Элементы.ДобавитьЗаявлениеНаВыпускСертификата.Видимость = Истина;
		
	Иначе
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДополнительноеПоле", "НЕОПРЕДЕЛЕНО");
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "И &ДополнительноеСоединение", "");
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ЭтоЗаявление", "Ложь");
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
				"ПеревыпуститьСертификат", "Видимость", Ложь);
		
		Элементы.СертификатыПоказатьЗаявления.Видимость  = Ложь;
		Элементы.СертификатыСостояниеЗаявления.Видимость = Ложь;
		Элементы.ДобавитьЗаявлениеНаВыпускСертификата.Видимость = Ложь;
	КонецЕсли;
	
	ЕстьПравоНаДобавлениеСертификатов =
		ПравоДоступа("Добавление", Метаданные.Справочники.СертификатыКлючейЭлектроннойПодписиИШифрования);
	
	СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка();
	СвойстваСписка.ТекстЗапроса = ТекстЗапроса;
	ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Сертификаты, СвойстваСписка);
	
	СертификатыВЛичномХранилище = Новый СписокЗначений;
	УстановитьПараметрыВСпискеСертификатовНаСервере();
	СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе);
	
	Если ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
		// Состав и настройки предусмотренных программ нельзя изменять.
		// Можно изменять только пути к программам на серверах Linux.
		Элементы.Программы.ИзменятьСоставСтрок = Ложь;
		Элементы.ПрограммыУстановитьПометкуУдаления.Доступность = Ложь;
		Элементы.ПрограммыКонтекстноеМенюПрограммыУстановитьПометкуУдаления.Доступность = Ложь;
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ПрограммыИзменить", "ТолькоВоВсехДействиях", Ложь);
	Иначе
		Элементы.НадписьНастройкаВЦентральномУзле.Видимость = Ложь;
	КонецЕсли;
	
	Если Не ЭлектроннаяПодписьСлужебный.ТребуетсяПутьКПрограмме(Истина) Тогда
		Элементы.ГруппаПрограммыLinuxПутьКПрограмме.Видимость = Ложь;
	КонецЕсли;
	
	Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = ОбщегоНазначения.ЭтоВебКлиент()
		И Параметры.Свойство("РасширениеНеПодключено");
	Элементы.ФормаУстановитьРасширение.Видимость = ОбщегоНазначения.ЭтоВебКлиент();
	
	ЗаполнитьПрограммыИНастройки();
	ОбновитьТекущуюВидимостьЭлементов();
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ОпределитьУстановленныеПрограммы();
	ПодключитьОбработчикОжидания("ДобавитьСертификатыВЛичномХранилищеВПараметрДинамическогоСписка", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриПовторномОткрытии()
	
	ОпределитьУстановленныеПрограммы();
	Если ЗначениеЗаполнено(Параметры.СертификатыПоказать) Тогда
		СертификатыПоказать = Параметры.СертификатыПоказать;
		СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	Если ВРег(ИмяСобытия) = ВРег("Запись_СертификатыКлючейЭлектроннойПодписиИШифрования") Тогда
		Если Не ЗначениеЗаполнено(Параметр) Тогда
			Элементы.Сертификаты.Обновить();
		ИначеЕсли Параметр.Установлен Тогда
			ПодключитьОбработчикОжидания("ОбновитьСписокСертификатов", 0.1, Истина);
		ИначеЕсли Параметр.ЭтоНовый Тогда
			Элементы.Сертификаты.Обновить();
			Элементы.Сертификаты.ТекущаяСтрока = Источник;
		Иначе
			Элементы.Сертификаты.Обновить();
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	// При изменении состава или настроек программ.
	Если ВРег(ИмяСобытия) = ВРег("Запись_ПрограммыЭлектроннойПодписиИШифрования")
	 Или ВРег(ИмяСобытия) = ВРег("Запись_ПутиКПрограммамЭлектроннойПодписиИШифрованияНаСерверахLinux")
	 Или ВРег(ИмяСобытия) = ВРег("Запись_ЛичныеНастройкиЭлектроннойПодписиИШифрования") Тогда
		
		ПодключитьОбработчикОжидания("ПриИзмененииСоставаИлиНастроекПрограмм", 0.1, Истина);
		Возврат;
	КонецЕсли;
	
	Если ВРег(ИмяСобытия) = ВРег("Установка_РасширениеРаботыСКриптографией")
		Или ВРег(ИмяСобытия) = ВРег("Установка_КомпонентаExtraCryptoAPI") Тогда
		ОпределитьУстановленныеПрограммы();
		Возврат;
	КонецЕсли;
	
	// При изменении настроек использования.
	Если ВРег(ИмяСобытия) <> ВРег("Запись_НаборКонстант") Тогда
		Возврат;
	КонецЕсли;
	
	Если ВРег(Источник) = ВРег("ИспользоватьЭлектронныеПодписи")
	 Или ВРег(Источник) = ВРег("ИспользоватьШифрование") Тогда
		
		ПодключитьОбработчикОжидания("ПриИзмененияИспользованияПодписанияИлиШифрования", 0.1, Истина);
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура СтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
	
	Если ПроверкаПрограммВыполнялась <> Истина Тогда
		ОпределитьУстановленныеПрограммы();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатыПоказатьПриИзменении(Элемент)
	
	СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе, ПользователиКлиент.ТекущийПользователь());
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатыПоказатьЗаявленияПриИзменении(Элемент)
	
	СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе);
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатыТолькоДействующиеПриИзменении(Элемент)

	СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе);

КонецПроцедуры

&НаКлиенте
Процедура ПользовательОтборПриИзменении(Элемент)
	
	СертификатыОбновитьОтбор(ЭтотОбъект, СостоянияЗаявленияНеВРаботе);
	
КонецПроцедуры

&НаКлиенте
Процедура РасширениеДляЗашифрованныхФайловПриИзменении(Элемент)
	
	Если ПустаяСтрока(РасширениеДляЗашифрованныхФайлов) Тогда
		РасширениеДляЗашифрованныхФайлов = "p7m";
	КонецЕсли;
	
	СохранитьНастройки();
	
КонецПроцедуры

&НаКлиенте
Процедура РасширениеДляФайловПодписиПриИзменении(Элемент)
	
	Если ПустаяСтрока(РасширениеДляФайловПодписи) Тогда
		РасширениеДляФайловПодписи = "p7s";
	КонецЕсли;
	
	СохранитьНастройки();
	
КонецПроцедуры

&НаКлиенте
Процедура ДействияПриСохраненииДанныхСЭлектроннойПодписьюПриИзменении(Элемент)
	
	СохранитьНастройки();
	
КонецПроцедуры

&НаКлиенте
Процедура СохранятьСертификатВместеСПодписьюПриИзменении(Элемент)
	СохранитьНастройки();
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыLinuxПутьКПрограммеПриИзменении(Элемент)
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СохранитьПутьКПрограмме();
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыLinuxПутьКПрограммеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		ДанныеВыбора = Неопределено;
		СтандартнаяОбработка = Ложь;
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("Программа", ТекущиеДанные.Ссылка);
	Строки = ПутиКПрограммамПоУмолчанию.НайтиСтроки(Отбор);
	Если Строки.Количество() = 0 Тогда
		ДанныеВыбора = Неопределено;
		СтандартнаяОбработка = Ложь;
		Возврат;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыLinuxПутьКПрограммеОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	Если Не ЗначениеЗаполнено(ВыбранноеЗначение)
		Или ТекущиеДанные = Неопределено Тогда
		
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("Программа", ТекущиеДанные.Ссылка);
	Строки = ПутиКПрограммамПоУмолчанию.НайтиСтроки(Отбор);
	ТекущиеДанные.LinuxПутьКПрограмме = ?(Строки.Количество() = 0, "", Строки[0].Путь);
	
	СохранитьПутьКПрограмме();
	
КонецПроцедуры

&НаКлиенте
Процедура ДекорацияПроверкаУстановкиКриптопровайдераОбработкаНавигационнойСсылки(
	Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	ПараметрыПроверки = Новый Структура;
	ПараметрыПроверки.Вставить("УстанавливатьРасширение", Истина);
	ПараметрыПроверки.Вставить("УстанавливатьКомпоненту", Истина);
	ПараметрыПроверки.Вставить("ПредлагатьУстановитьПрограмму", Истина);
	ПараметрыПроверки.Вставить("РасширенноеОписание", Истина);
	
	ОповещениеПослеПроверкиПрограмм = Новый ОписаниеОповещения(
		"ОпределитьУстановленныеПрограммыПослеПроверкиПрограммКриптографии", ЭтотОбъект);
	ЭлектроннаяПодписьСлужебныйКлиент.ПроверитьУстановкуПрограммКриптографии(ЭтотОбъект, ПараметрыПроверки,
		Новый ОписаниеОповещения("ПослеПроверкиПрограммКриптографии", ЭтотОбъект, ОповещениеПослеПроверкиПрограмм));

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыСертификаты

&НаКлиенте
Процедура СертификатыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Отказ = Истина;
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	
	Если Копирование И ЗаявлениеНаВыпускСертификатаДоступно Тогда
		Если Элементы.Сертификаты.ТекущаяСтрока = Неопределено Тогда
			Возврат;
		КонецЕсли;
		ТекущиеДанные = СертификатыТекущиеДанные(Элементы.Сертификаты);
		ПараметрыСоздания.СоздатьЗаявление = Истина;
		ПараметрыСоздания.СертификатОснование = ТекущиеДанные.Ссылка;
	Иначе
		ПараметрыСоздания.СкрытьЗаявление = Не ЗаявлениеНаВыпускСертификатаДоступно;
	КонецЕсли;
	
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификат(ПараметрыСоздания);
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СертификатыПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
	
	Для Каждого Строка Из Строки Цикл
		Если НЕ Строка.Значение.Данные.Свойство("Пользователь") Тогда
			Возврат;
		КонецЕсли;
		Прервать;
	КонецЦикла;
	
	Запрос = Неопределено;
	Для Каждого Строка Из Строки Цикл
		Если ЗначениеЗаполнено(Строка.Значение.Данные.Пользователь) Тогда
			Продолжить;
		КонецЕсли;
		Если Запрос = Неопределено Тогда
			Запрос = Новый Запрос;
			Запрос.Текст =
			"ВЫБРАТЬ
			|	СертификатыКлючейЭлектроннойПодписиИШифрованияПользователи.Ссылка КАК Ссылка,
			|	СертификатыКлючейЭлектроннойПодписиИШифрованияПользователи.Пользователь КАК Пользователь,
			|	Представление(СертификатыКлючейЭлектроннойПодписиИШифрованияПользователи.Пользователь) КАК ПользовательПредставление
			|ИЗ
			|	Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Пользователи КАК
			|		СертификатыКлючейЭлектроннойПодписиИШифрованияПользователи
			|ГДЕ
			|	СертификатыКлючейЭлектроннойПодписиИШифрованияПользователи.Ссылка В (&Ссылки)
			|ИТОГИ
			|	КОЛИЧЕСТВО(Пользователь)
			|ПО
			|	Ссылка";
			Запрос.УстановитьПараметр("Ссылки", Строки.ПолучитьКлючи());
			РезультатЗапроса = Запрос.Выполнить(); // @skip-check query-in-loop - Запрос выполняется один раз
			Если РезультатЗапроса.Пустой() Тогда
				Возврат;
			КонецЕсли;
			ВыборкаСсылка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		КонецЕсли;
		Если ВыборкаСсылка.НайтиСледующий(Строка.Значение.Данные["Ссылка"], "Ссылка") Тогда
			КоличествоПользователей = ВыборкаСсылка.Пользователь;
			ВыборкаПользователь = ВыборкаСсылка.Выбрать();
			ВыборкаПользователь.Следующий();
			Если КоличествоПользователей = 1 Тогда
				Строка.Значение.Данные.Пользователь = ВыборкаПользователь.ПользовательПредставление;
				Продолжить;
			КонецЕсли;
			Пользователь1 = ВыборкаПользователь.ПользовательПредставление;
			ВыборкаПользователь.Следующий();
			Пользователь2 = ВыборкаПользователь.ПользовательПредставление;
			Строка.Значение.Данные.Пользователь = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПользователиСертификатаСтрокой(
				Пользователь1, Пользователь2, КоличествоПользователей);
		КонецЕсли;
	КонецЦикла;
		
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыПрограммы

&НаКлиенте
Процедура ПрограммыПриАктивизацииСтроки(Элемент)
	
	Элементы.ПрограммыУстановитьПометкуУдаления.Доступность =
		Элементы.Программы.ТекущиеДанные <> Неопределено;
	
	Если Элементы.Программы.ТекущиеДанные <> Неопределено Тогда
		LinuxПутьКТекущейПрограмме = Элементы.Программы.ТекущиеДанные.LinuxПутьКПрограмме;
	КонецЕсли;
	
	ОбновитьLinuxПутьКПрограмме();
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Отказ = Истина;
	
	Если Элементы.Программы.ИзменятьСоставСтрок Тогда
		Если ЭлектроннаяПодписьСлужебныйКлиент.ИспользоватьСервисОблачнойПодписи() Тогда
			МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент");
			МодульСервисКриптографииDSSКлиент.ДобавлениеПрограммыЭлектроннойПодписи(Неопределено);
		Иначе	
			ОткрытьФорму("Справочник.ПрограммыЭлектроннойПодписиИШифрования.ФормаОбъекта");
		КонецЕсли;	
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыПередНачаломИзменения(Элемент, Отказ)
	
	Отказ = Истина;
	
	Если Элементы.Найти("ПрограммыИзменить") <> Неопределено
	   И Элементы.ПрограммыИзменить.Видимость Тогда
		Если ЗначениеЗаполнено(Элементы.Программы.ТекущиеДанные.Ссылка) Тогда
			ПоказатьЗначение(, Элементы.Программы.ТекущиеДанные.Ссылка);
		Иначе
			РасширенноеОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеРасширенноеОписаниеПрограммы();
			ЗаполнитьЗначенияСвойств(РасширенноеОписаниеПрограммы, Элементы.Программы.ТекущиеДанные);
			РасширенноеОписаниеПрограммы.Представление = Элементы.Программы.ТекущиеДанные.Наименование;
			ПараметрыФормы = Новый Структура("Программа, РежимИспользования", РасширенноеОписаниеПрограммы,
				ПредопределенноеЗначение("Перечисление.РежимыИспользованияПрограммыЭлектроннойПодписи.Настроена"));
			ОткрытьФорму("Справочник.ПрограммыЭлектроннойПодписиИШифрования.ФормаОбъекта", ПараметрыФормы, ЭтотОбъект,,,,,
				РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыПередУдалением(Элемент, Отказ)
	
	Отказ = Истина;
	
	Если Элементы.Найти("ПрограммыИзменить") <> Неопределено
	   И Элементы.ПрограммыИзменить.Видимость Тогда
		
		ПрограммыУстановитьПометкуУдаления(Неопределено);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИнструкцияНажатие(Элемент)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОткрытьИнструкциюПоРаботеСПрограммами();
	
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	Если Поле = Элементы.ПрограммыПодробнее
		И Не ПустаяСтрока(ТекущиеДанные.Подробнее) Тогда
		
		СтандартнаяОбработка = Ложь;
		
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("ЗаголовокПредупреждения", НСтр("ru = 'Результат проверки программы'"));
		ПараметрыФормы.Вставить("ТекстОшибкиКлиент", ТекущиеДанные.РезультатПроверки);
		ПараметрыФормы.Вставить("ТекстОшибкиСервер", ТекущиеДанные.РезультатПроверкиНаСервере);
		ПараметрыФормы.Вставить("ПоказатьТребуетсяПомощь", Истина);
		ПараметрыФормы.Вставить("ПоказатьИнструкцию", Истина);
		
		ОткрытьФорму("ОбщаяФорма.РасширенноеПредставлениеОшибки", ПараметрыФормы, ЭтотОбъект);
	
	ИначеЕсли Не ЗначениеЗаполнено(ТекущиеДанные.Ссылка) Тогда
	
		СтандартнаяОбработка = Ложь;
		ОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеРасширенноеОписаниеПрограммы();
		ЗаполнитьЗначенияСвойств(ОписаниеПрограммы, ТекущиеДанные);
		ОписаниеПрограммы.Представление = ТекущиеДанные.Наименование;
		ОткрытьФорму("Справочник.ПрограммыЭлектроннойПодписиИШифрования.Форма.ПрограммаОпределеннаяАвтоматически",
			Новый Структура("Программа", ОписаниеПрограммы), ЭтотОбъект,,,,,РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
			
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ОткрытьМашиночитаемыеДоверенности(Команда)
	
	// Локализация
	
	Если Не ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности") Тогда
		Возврат;
	КонецЕсли;
	
	МодульМашиночитаемыеДоверенностиФНСКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("МашиночитаемыеДоверенностиФНСКлиент");
	МодульМашиночитаемыеДоверенностиФНСКлиент.ОткрытьСписокМЧД();
	
	// Конец Локализация
	
КонецПроцедуры

&НаКлиенте
Процедура Обновить(Команда)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОчиститьКэшУстановленныхКриптопровайдеров();
	ЗаполнитьПрограммыИНастройки(Истина);
	ОпределитьУстановленныеПрограммы();
	ОбновитьСписокСертификатов();
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьЗаявлениеНаВыпускСертификата(Команда)
	
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	ПараметрыСоздания.СоздатьЗаявление = Истина;
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификатПослеВыбораНазначения("ЗаявлениеНаВыпускСертификата", 
		ПараметрыСоздания);
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьДляПодписанияИШифрования(Команда)
	
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификатПослеВыбораНазначения(НазначениеДляПодписанияИШифрования,
		ПараметрыСоздания);
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьИзФайлов(Команда)
	
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификатПослеВыбораНазначения("ТолькоДляШифрованияИзФайлов",
		ПараметрыСоздания);
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьИзКаталога(Команда)
	
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификатПослеВыбораНазначения("ТолькоДляШифрованияИзКаталога",
		ПараметрыСоздания);
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьТолькоДляШифрования(Команда)
	
	ПараметрыСоздания = ЭлектроннаяПодписьСлужебныйКлиент.ПараметрыДобавленияСертификата();
	ЭлектроннаяПодписьСлужебныйКлиент.ДобавитьСертификатПослеВыбораНазначения("ТолькоДляШифрования",
		ПараметрыСоздания);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьРасширение(Команда)
	
	ЭлектроннаяПодписьКлиент.УстановитьРасширение(Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьВерсиюКомпонентыExtraCryptoAPI(Команда)
	
	УстановитьПодключитьСообщитьВерсиюКомпоненты(Ложь);
		
КонецПроцедуры

&НаКлиенте
Процедура УстановитьКомпонентуExtraCryptoAPI(Команда)
	
	УстановитьПодключитьСообщитьВерсиюКомпоненты(Истина);

КонецПроцедуры

&НаКлиенте
Процедура ТехническаяИнформация(Команда)
	
	ЭлектроннаяПодписьСлужебныйКлиент.СформироватьТехническуюИнформацию(
		НСтр("ru = 'Настройки электронной подписи и шифрования'"));
			
КонецПроцедуры

&НаКлиенте
Процедура ПрограммыУстановитьПометкуУдаления(Команда)
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ТекущиеДанные.Ссылка) Тогда
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ПометкаУдаления Тогда
		ТекстВопроса = НСтр("ru = 'Снять с ""%1"" пометку на удаление?'");
	Иначе
		ТекстВопроса = НСтр("ru = 'Пометить ""%1"" на удаление?'");
	КонецЕсли;
	
	СодержимоеВопроса = Новый Массив;
	СодержимоеВопроса.Добавить(БиблиотекаКартинок.Вопрос32);
	СодержимоеВопроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстВопроса, ТекущиеДанные.Наименование));
	
	ПоказатьВопрос(
		Новый ОписаниеОповещения("ПрограммыУстановитьПометкуУдаленияПродолжить", ЭтотОбъект, ТекущиеДанные.Ссылка),
		Новый ФорматированнаяСтрока(СодержимоеВопроса),
		РежимДиалогаВопрос.ДаНет);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаКлиенте
Процедура ОбновитьСписокСертификатов()

	СертификатыВЛичномХранилище = Новый СписокЗначений;
	ОписаниеОповещения = Новый ОписаниеОповещения(
		"ОбновитьСписокСертификатовПослеПолученияСвойствСертификатовНаКлиенте",
		ЭтотОбъект, "ОбновитьНаСервере");
	ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьСвойстваСертификатовНаКлиенте(ОписаниеОповещения, Истина, Истина, Истина);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьСертификатыВЛичномХранилищеВПараметрДинамическогоСписка()
				
	ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьСвойстваСертификатовНаКлиенте(
		Новый ОписаниеОповещения("ОбновитьСписокСертификатовПослеПолученияСвойствСертификатовНаКлиенте", ЭтотОбъект),
		Истина, Истина, Истина);

КонецПроцедуры

&НаКлиенте
Процедура ОбновитьСписокСертификатовПослеПолученияСвойствСертификатовНаКлиенте(Результат, Параметры) Экспорт
	
	Для Каждого КлючИЗначение Из Результат.СвойстваСертификатовНаКлиенте Цикл
		СертификатыВЛичномХранилище.Добавить(КлючИЗначение.Ключ); 
	КонецЦикла;
	
	Если Параметры = "ОбновитьНаСервере" Тогда
		УстановитьПараметрыВСпискеСертификатовНаСервере()
	Иначе	
		ТекущаяДата = ОбщегоНазначенияКлиент.ДатаУниверсальная();
		УстановитьПараметрыВСпискеСертификатов(ЭтотОбъект, СертификатыВЛичномХранилище, ТекущаяДата);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьПараметрыВСпискеСертификатов(Форма, СписокСертификатов, ТекущаяДата)
	
	ОбщегоНазначенияКлиентСервер.УстановитьПараметрДинамическогоСписка(
		Форма.Сертификаты, "СертификатыВЛичномХранилище", СписокСертификатов, Истина);
	ОбщегоНазначенияКлиентСервер.УстановитьПараметрДинамическогоСписка(
		Форма.Сертификаты, "ТекущаяДата", ТекущаяДата, Истина);

КонецПроцедуры

&НаСервере
Процедура УстановитьПараметрыВСпискеСертификатовНаСервере()

	ЭлектроннаяПодписьСлужебный.ДополнитьСписокСертификатовВЛичномХранилищеНаСервере(СертификатыВЛичномХранилище);
	УстановитьПараметрыВСпискеСертификатов(ЭтотОбъект, СертификатыВЛичномХранилище, ТекущаяУниверсальнаяДата());
	
КонецПроцедуры	

&НаСервере
Процедура УстановитьУсловноеОформление()
	
	ЭлементУсловногоОформления = УсловноеОформление.Элементы.Добавить();
	
	ЭлементЦветаОформления = ЭлементУсловногоОформления.Оформление.Элементы.Найти("TextColor");
	ЭлементЦветаОформления.Значение = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
	ЭлементЦветаОформления.Использование = Истина;
	
	ЭлементОтбораДанных = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбораДанных.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Программы.Установлена");
	ЭлементОтбораДанных.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбораДанных.ПравоеЗначение = Ложь;
	ЭлементОтбораДанных.Использование  = Истина;
	
	ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("ПрограммыРезультатПроверки");
	ЭлементОформляемогоПоля.Использование = Истина;
	
	ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("ПрограммыНаименование");
	ЭлементОформляемогоПоля.Использование = Истина;
	
	Если Элементы.ПрограммыРезультатПроверкиНаСервере.Видимость Тогда
		ЭлементУсловногоОформления = УсловноеОформление.Элементы.Добавить();
	
		ЭлементЦветаОформления = ЭлементУсловногоОформления.Оформление.Элементы.Найти("TextColor");
		ЭлементЦветаОформления.Значение = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
		ЭлементЦветаОформления.Использование = Истина;
		
		ЭлементОтбораДанных = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		ЭлементОтбораДанных.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Программы.УстановленаНаСервере");
		ЭлементОтбораДанных.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
		ЭлементОтбораДанных.ПравоеЗначение = Ложь;
		ЭлементОтбораДанных.Использование  = Истина;
		
		ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
		ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("ПрограммыРезультатПроверкиНаСервере");
		ЭлементОформляемогоПоля.Использование = Истина;

	КонецЕсли;
	
	ЭлементУсловногоОформления = УсловноеОформление.Элементы.Добавить();
	
	ЭлементЦветаОформления = ЭлементУсловногоОформления.Оформление.Элементы.Найти("TextColor");
	ЭлементЦветаОформления.Значение = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
	ЭлементЦветаОформления.Использование = Истина;
	
	ЭлементОтбораДанных = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбораДанных.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Сертификаты.Отозван");
	ЭлементОтбораДанных.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбораДанных.ПравоеЗначение = Истина;
	ЭлементОтбораДанных.Использование  = Истина;
	
	ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("Сертификаты");
	ЭлементОформляемогоПоля.Использование = Истина;
		
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура СертификатыОбновитьОтбор(Форма, СостоянияЗаявленияНеВРаботе, ТекущийПользователь = Неопределено)
	
	Элементы = Форма.Элементы;
	
	// Отбор сертификатов Все/Мои.
	ПоказатьСвои = Форма.СертификатыПоказать <> "ВсеСертификаты";
	Если ТекущийПользователь <> Неопределено Тогда
		Если ПоказатьСвои Тогда
			Форма.ПользовательОтбор = ТекущийПользователь;
		Иначе
			Форма.ПользовательОтбор = Неопределено;
		КонецЕсли;
	КонецЕсли;
	
	// Отбор по пользователю.
	Элементы.СертификатыПользователь.Видимость = Не ПоказатьСвои;
	Элементы.ПользовательОтбор.Видимость = Не ПоказатьСвои;
	Форма.Сертификаты.Параметры.УстановитьЗначениеПараметра("ПользовательСертификата", ?(ЗначениеЗаполнено(
		Форма.ПользовательОтбор), Форма.ПользовательОтбор, Неопределено));
	
	// Отбор по действующим.
	ОтборПоДействующим = Не Форма.СертификатыПоказать = "МоиСертификатыСИстекающимСрокомДействия" 
						И Не Форма.СертификатыПоказать = "МоиЗаявленияВРаботе";
							
	Элементы.СертификатыТолькоДействующие.Видимость = ОтборПоДействующим;
	ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Форма.Сертификаты,
		"Действует", Истина, , , ОтборПоДействующим И Форма.СертификатыТолькоДействующие);
	
	ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Форма.Сертификаты,
		"СрокДействияСкороЗакончится", Истина, , ,Форма.СертификатыПоказать = "МоиСертификатыСИстекающимСрокомДействия");
		
	Если Форма.СертификатыПоказать = "МоиЗаявленияВРаботе" Тогда
		
		Форма.СертификатыПоказатьЗаявления = Неопределено;
		Форма.Элементы.СертификатыПоказатьЗаявления.Видимость = Ложь;
		
		ОтборПоСостояниюЗаявления = Неопределено;
		ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Форма.Сертификаты,
			"СостояниеЗаявления", СостоянияЗаявленияНеВРаботе, ВидСравненияКомпоновкиДанных.НеВСписке, , Истина);
	Иначе
		
		Форма.Элементы.СертификатыПоказатьЗаявления.Видимость = Форма.ЗаявлениеНаВыпускСертификатаДоступно
			И Не Форма.СертификатыПоказать = "МоиСертификатыСИстекающимСрокомДействия";
		
		Если Элементы.СертификатыПоказатьЗаявления.Видимость Тогда
			// Отбор сертификатов по состоянию заявления.
			ОтборПоСостояниюЗаявления = ЗначениеЗаполнено(Форма.СертификатыПоказатьЗаявления);
			ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(Форма.Сертификаты,
				"СостояниеЗаявления", Форма.СертификатыПоказатьЗаявления, , , ОтборПоСостояниюЗаявления);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  ТаблицаФормы - ДанныеФормыКоллекция
// 
// Возвращаемое значение:
//  Структура:
//    * Ссылка - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования
//
&НаКлиенте
Функция СертификатыТекущиеДанные(ТаблицаФормы)
	
	Возврат ТаблицаФормы.ТекущиеДанные;
	
КонецФункции

&НаКлиенте
Процедура ПрограммыУстановитьПометкуУдаленияПродолжить(Ответ, ТекущаяПрограмма) Экспорт
	
	Если Ответ = КодВозвратаДиалога.Да Тогда
		ИзменитьПометкуУдаленияПрограммы(ТекущаяПрограмма);
		ОповеститьОбИзменении(ТекущаяПрограмма);
		Оповестить("Запись_ПрограммыЭлектроннойПодписиИШифрования", Новый Структура, ТекущаяПрограмма);
		ОпределитьУстановленныеПрограммы();
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ИзменитьПометкуУдаленияПрограммы(Программа)
	
	Если ТипЗнч(Программа) = ЭлектроннаяПодписьСлужебный.ТипПрограммыСервисаПодписи() Тогда
		МодульСервисКриптографииDSSСлужебный = ОбщегоНазначения.ОбщийМодуль("СервисКриптографииDSSСлужебный");
		МодульСервисКриптографииDSSСлужебный.ИзменитьПометкуУдаленияПрограммы(Программа, УникальныйИдентификатор);
		
	Иначе
		ЗаблокироватьДанныеДляРедактирования(Программа, , УникальныйИдентификатор);
		
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.ПрограммыЭлектроннойПодписиИШифрования");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", Программа);
		
		НачатьТранзакцию();
		Попытка
			
			Блокировка.Заблокировать();
			
			Объект = Программа.ПолучитьОбъект();
			Объект.ПометкаУдаления = Не Объект.ПометкаУдаления;
			Если Объект.ПометкаУдаления Тогда
				Объект.РежимИспользования = Перечисления.РежимыИспользованияПрограммыЭлектроннойПодписи.НеИспользуется;
			Иначе
				Объект.РежимИспользования = Перечисления.РежимыИспользованияПрограммыЭлектроннойПодписи.Настроена;
			КонецЕсли;
			Объект.Записать();
			
			ЗафиксироватьТранзакцию();
			
		Исключение
			ОтменитьТранзакцию();
			РазблокироватьДанныеДляРедактирования(Программа, УникальныйИдентификатор);
			ВызватьИсключение;
		КонецПопытки;
		
		РазблокироватьДанныеДляРедактирования(Программа, УникальныйИдентификатор);
	КонецЕсли;
	
	ЗаполнитьПрограммыИНастройки(Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриИзмененияИспользованияПодписанияИлиШифрования()
	
	ОбновитьТекущуюВидимостьЭлементов();
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьТекущуюВидимостьЭлементов()
	
	Если ЭлектроннаяПодпись.ИспользоватьЭлектронныеПодписи() Тогда
		Элементы.РасширениеДляФайловПодписи.Видимость = Истина;
		Элементы.ДействияПриСохраненииДанныхСЭлектроннойПодписью.Видимость = Истина;
	Иначе
		Элементы.РасширениеДляФайловПодписи.Видимость = Ложь;
		Элементы.ДействияПриСохраненииДанныхСЭлектроннойПодписью.Видимость = Ложь;
	КонецЕсли;
	
	Элементы.РасширениеДляЗашифрованныхФайлов.Видимость = ЭлектроннаяПодпись.ИспользоватьШифрование();
	
	Если Не ЕстьПравоНаДобавлениеСертификатов Тогда
		
		Элементы.ГруппаДобавитьСертификаты.Видимость = Ложь;
		Элементы.ДобавитьЗаявлениеНаВыпускСертификата.Видимость = Ложь;
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
			Элементы, "ПеревыпуститьСертификат", "Видимость", Ложь);
		Возврат;
	КонецЕсли;

	Элементы.ДобавитьЗаявлениеНаВыпускСертификата.Видимость = ЗаявлениеНаВыпускСертификатаДоступно;
		
	Если ЭлектроннаяПодпись.ДобавлениеИзменениеЭлектронныхПодписей() Тогда
		
		Элементы.ДобавитьДляПодписанияИШифрования.Заголовок = НСтр("ru = 'Для подписания и шифрования...'");

		Если ЭлектроннаяПодписьСлужебный.ИспользоватьСервисОблачнойПодписи() Тогда
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для подписания и шифрования из установленных на сервере DSS и на компьютере'");
		ИначеЕсли ЭлектроннаяПодписьСлужебный.ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для подписания и шифрования из установленных в сервисе и на компьютере'");
		Иначе
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для подписания и шифрования из установленных на компьютере'");
		КонецЕсли;
		
		НазначениеДляПодписанияИШифрования = "ДляПодписанияШифрованияИРасшифровки";
	
	Иначе
	
		Элементы.ДобавитьДляПодписанияИШифрования.Заголовок = НСтр("ru = 'Для шифрования и расшифровки...'");

		Если ЭлектроннаяПодписьСлужебный.ИспользоватьСервисОблачнойПодписи() Тогда
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для шифрования и расшифровки из установленных на сервере DSS и на компьютере'");
		ИначеЕсли ЭлектроннаяПодписьСлужебный.ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для шифрования и расшифровки из установленных в сервисе и на компьютере'");
		Иначе
			Элементы.ДобавитьДляПодписанияИШифрования.РасширеннаяПодсказка.Заголовок = НСтр(
				"ru = 'Добавить для шифрования и расшифровки из установленных на компьютере'");
		КонецЕсли;
		
		НазначениеДляПодписанияИШифрования = "ДляШифрованияИРасшифровки";
	
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОпределитьУстановленныеПрограммы()
	
	Если Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаПрограммы Тогда
		ПроверкаПрограммВыполнялась = Истина;
		НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения(
			"ОпределитьУстановленныеПрограммыПослеПодключенияРасширения", ЭтотОбъект));
	Иначе
		ПроверкаПрограммВыполнялась = Неопределено;
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ОпределитьУстановленныеПрограммы.
&НаКлиенте
Процедура ОпределитьУстановленныеПрограммыПослеПодключенияРасширения(Подключено, Контекст) Экспорт
	
	Если Подключено Тогда
		Элементы.СтраницыПрограммыИОбновление.ТекущаяСтраница = Элементы.СтраницаПрограммыОбновление;
	КонецЕсли;
	
	#Если ВебКлиент Тогда
		ПодключитьОбработчикОжидания("ОбработчикОжиданияОпределитьУстановленныеПрограммы", 0.3, Истина);
	#Иначе
		ПодключитьОбработчикОжидания("ОбработчикОжиданияОпределитьУстановленныеПрограммы", 0.1, Истина);
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикОжиданияДляПродолжения()
	
	Возврат;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикОжиданияОпределитьУстановленныеПрограммы()
	
	НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения(
		"ОбработчикОжиданияОпределитьУстановленныеПрограммыПослеПодключенияРасширения", ЭтотОбъект));
	
	#Если ВебКлиент Тогда
		ПодключитьОбработчикОжидания("ОбработчикОжиданияДляПродолжения", 0.3, Истина);
	#Иначе
		ПодключитьОбработчикОжидания("ОбработчикОжиданияДляПродолжения", 0.1, Истина);
	#КонецЕсли
	
КонецПроцедуры

// Продолжение процедуры ОбработчикОжиданияОпределитьУстановленныеПрограммы.
&НаКлиенте
Процедура ОбработчикОжиданияОпределитьУстановленныеПрограммыПослеПодключенияРасширения(Подключено, Контекст) Экспорт
	
	Если Не Подключено Тогда
		Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Истина;
		Элементы.ДекорацияПроверкаУстановкиКриптопровайдера.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
			НСтр("ru = '<a href = ""%1"">Нажмите здесь</a>, чтобы установить расширение для работы с электронной подписью и увидеть все установленные на компьютере программы для работы с электронной подписью.'"),
			"ПроверитьУстановкуПрограммКриптографии");
		ПодключитьОбработчикОжидания("ОбработчикОжиданияОпределитьУстановленныеПрограммы", 3, Истина);
		Возврат;
	КонецЕсли;
	
	ПутиКПрограммамПоУмолчанию.Очистить();
	
	ПараметрыПроверки = Новый Структура;
	ПараметрыПроверки.Вставить("УстанавливатьРасширение", Ложь);
	ПараметрыПроверки.Вставить("УстанавливатьКомпоненту", Ложь);
	ПараметрыПроверки.Вставить("ПредлагатьУстановитьПрограмму", Ложь);
	ПараметрыПроверки.Вставить("ПроверятьНаСервере", Ложь);
	ПараметрыПроверки.Вставить("РасширенноеОписание", Истина);
	
	ОповещениеПослеПроверкиПрограмм = Новый ОписаниеОповещения(
		"ОпределитьУстановленныеПрограммыПослеПроверкиПрограммКриптографии", ЭтотОбъект, Контекст);
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПроверитьУстановкуПрограммКриптографии(ЭтотОбъект, ПараметрыПроверки,
		Новый ОписаниеОповещения("ПослеПроверкиПрограммКриптографии", ЭтотОбъект, ОповещениеПослеПроверкиПрограмм));

КонецПроцедуры

&НаКлиенте
Асинх Процедура ОпределитьУстановленныеПрограммыПослеПроверкиПрограммКриптографии(Результат, Контекст) Экспорт
	
	Подключено = Ждать ПодключитьРасширениеРаботыСКриптографиейАсинх();
	
	Если Не Подключено Тогда
		Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Истина;
		Элементы.ДекорацияПроверкаУстановкиКриптопровайдера.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
			НСтр("ru = '<a href = ""%1"">Нажмите здесь</a>, чтобы установить расширение для работы с электронной подписью и увидеть все установленные на компьютере программы для работы с электронной подписью.'"),
			"ПроверитьУстановкуПрограммКриптографии");
	КонецЕсли;
	
	Контекст = Новый Структура;
	Контекст.Вставить("Индекс", -1);
	Контекст.Вставить("РасширениеПодключено", Подключено);
	
	ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
	
КонецПроцедуры

// Продолжение процедуры ОбработчикОжиданияОпределитьУстановленныеПрограммы.
&НаКлиенте
Процедура ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст)
	
	Если Программы.Количество() <= Контекст.Индекс + 1 Тогда
		// После цикла.
		Элементы.СтраницыПрограммыИОбновление.ТекущаяСтраница = Элементы.СтраницаПрограммыСписок;
		ТекущийЭлемент = Элементы.Программы;
		ОбновитьLinuxПутьКПрограмме();
		Возврат;
	КонецЕсли;
	Контекст.Индекс = Контекст.Индекс + 1;
	ОписаниеПрограммы = Программы.Получить(Контекст.Индекс);

	Контекст.Вставить("ОписаниеПрограммы", ОписаниеПрограммы);
	
	Если ОписаниеПрограммы.Автоопределение Тогда
		ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклПослеПолученияПутиКПрограмме(Неопределено, Контекст);
	Иначе
		ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьПутьКПрограммеПоУмолчанию(Новый ОписаниеОповещения(
			"ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклПослеПолученияПутиКПрограмме", ЭтотОбъект, Контекст),
			ОписаниеПрограммы.Ссылка);
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ОбработчикОжиданияОпределитьУстановленныеПрограммы.
&НаКлиенте
Процедура ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклПослеПолученияПутиКПрограмме(ОписаниеПути, Контекст) Экспорт
	
	ОписаниеПрограммы = Контекст.ОписаниеПрограммы;
	
	Если ЗначениеЗаполнено(ОписаниеПути) И ЗначениеЗаполнено(ОписаниеПути.ПутьКПрограмме) Тогда
		НоваяСтрока = ПутиКПрограммамПоУмолчанию.Добавить();
		НоваяСтрока.Программа = ОписаниеПрограммы.Ссылка;
		НоваяСтрока.Путь = ОписаниеПути.ПутьКПрограмме;
	КонецЕсли;
	
	Если ОписаниеПрограммы.ПометкаУдаления Тогда
		ОбновитьЗначение(ОписаниеПрограммы.РезультатПроверки, "");
		ОбновитьЗначение(ОписаниеПрограммы.Подробнее, "");
		ОбновитьЗначение(ОписаниеПрограммы.Установлена, "");
		ОбновитьЗначение(ОписаниеПрограммы.УстановленаНаСервере, "");
		ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
		Возврат;
	ИначеЕсли ОписаниеПрограммы.ЭтоВстроенныйКриптопровайдер
		Или ЭлектроннаяПодписьСлужебныйКлиентСервер.РазмещениеСертификата(ОписаниеПрограммы.ТипРазмещения) = "ОблачнаяПодпись" Тогда
		
		ОбновитьЗначение(ОписаниеПрограммы.РезультатПроверки, НСтр("ru = 'Доступен.'"));
		ОбновитьЗначение(ОписаниеПрограммы.Установлена, Истина);
		ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
		Возврат;
	КонецЕсли;
	
	Если Не Контекст.РасширениеПодключено Тогда
		ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
		Возврат;
	КонецЕсли;
	
	ОписанияПрограмм = Новый Массив;
	ОписанияПрограмм.Добавить(Контекст.ОписаниеПрограммы);
	
	ОписаниеОшибок = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеОписаниеОшибок();
	
	ПараметрыВыполнения = Новый Структура;
	ПараметрыВыполнения.Вставить("ОписанияПрограмм",  ОписанияПрограмм);
	ПараметрыВыполнения.Вставить("Индекс",            -1);
	ПараметрыВыполнения.Вставить("ПоказатьОшибку",    Неопределено);
	ПараметрыВыполнения.Вставить("ОписаниеОшибок",    ОписаниеОшибок);
	ПараметрыВыполнения.Вставить("АлгоритмПодписи",   "");
	ПараметрыВыполнения.Вставить("ИнтерактивныйРежим", Ложь);
	ПараметрыВыполнения.Вставить("ЭтоLinux",   ЭлектроннаяПодписьСлужебныйКлиент.ТребуетсяПутьКПрограмме());
	ПараметрыВыполнения.Вставить("Менеджер",   Неопределено);
	ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения(
		"ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклПродолжение", ЭтотОбъект, Контекст));
	
	Контекст.Вставить("ПараметрыВыполнения", Новый Структура("ОписаниеОшибок", ОписаниеОшибок));
	
	ЭлектроннаяПодписьСлужебныйКлиент.СоздатьМенеджерКриптографииЦиклНачало(ПараметрыВыполнения);
	
КонецПроцедуры

// Продолжение процедуры ОбработчикОжиданияОпределитьУстановленныеПрограммы.
&НаКлиенте
Процедура ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклПродолжение(Менеджер, Контекст) Экспорт
	
	ОписаниеПрограммы = Контекст.ОписаниеПрограммы;
	Ошибки = Контекст.ПараметрыВыполнения.ОписаниеОшибок.Ошибки; // Массив Из см. ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки
	
	Если Менеджер <> Неопределено Тогда
		ОбновитьЗначение(ОписаниеПрограммы.РезультатПроверки, НСтр("ru = 'Установлена на компьютере.'"));
		Если ЗначениеЗаполнено(ОписаниеПрограммы.РезультатПроверкиНаСервере)
			И ОписаниеПрограммы.УстановленаНаСервере <> Истина Тогда
			ОбновитьЗначение(ОписаниеПрограммы.Подробнее, НСтр("ru = 'Подробнее'") + "...");
		Иначе
			ОбновитьЗначение(ОписаниеПрограммы.Подробнее, "");
		КонецЕсли;
		ОбновитьЗначение(ОписаниеПрограммы.Установлена, Истина);
		ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
		Возврат;
	КонецЕсли;
	
	Для каждого Ошибка Из Ошибки Цикл
		Прервать;
	КонецЦикла;
	
	Если Ошибка.НеУказанПуть Тогда
		ОбновитьЗначение(ОписаниеПрограммы.РезультатПроверки, Ошибка.Описание);
		ОбновитьЗначение(ОписаниеПрограммы.Подробнее, НСтр("ru = 'Подробнее'") + "...");
		ОбновитьЗначение(ОписаниеПрограммы.Установлена, "");
	Иначе
		ТекстОшибки = НСтр("ru = 'Не установлена на компьютере.'") + " " + Ошибка.Описание;
		Если Ошибка.КАдминистратору И Не ЭтоПолноправныйПользователь Тогда
			ТекстОшибки = ТекстОшибки + " " + НСтр("ru = 'Обратитесь к администратору.'");
		КонецЕсли;
		ОбновитьЗначение(ОписаниеПрограммы.РезультатПроверки, ТекстОшибки);
		ОбновитьЗначение(ОписаниеПрограммы.Подробнее, НСтр("ru = 'Подробнее'") + "...");
		ОбновитьЗначение(ОписаниеПрограммы.Установлена, Ложь);
	КонецЕсли;
	
	ОбработчикОжиданияОпределитьУстановленныеПрограммыЦиклНачало(Контекст);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьLinuxПутьКПрограмме()
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	
	ПутьПоУмолчанию = "";
	Если ТекущиеДанные <> Неопределено Тогда
		Если ТекущиеДанные.Автоопределение Тогда
			Элементы.ПрограммыLinuxПутьКПрограмме.КнопкаВыпадающегоСписка = Ложь;
			Элементы.ПрограммыLinuxПутьКПрограмме.ТолькоПросмотр = Истина;
			Элементы.ПрограммыLinuxПутьКПрограмме.ПодсказкаВвода = НСтр("ru = 'Определяется автоматически'");
			Возврат;
		КонецЕсли;
		
		Отбор = Новый Структура("Программа", ТекущиеДанные.Ссылка);
		Строки = ПутиКПрограммамПоУмолчанию.НайтиСтроки(Отбор);
		Если Строки.Количество() > 0 Тогда
			ПутьПоУмолчанию = Строки[0].Путь;
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ПрограммыLinuxПутьКПрограмме.КнопкаВыпадающегоСписка = ЗначениеЗаполнено(ПутьПоУмолчанию);
	Элементы.ПрограммыLinuxПутьКПрограмме.ПодсказкаВвода = ПутьПоУмолчанию;
	Элементы.ПрограммыLinuxПутьКПрограмме.ТолькоПросмотр = Ложь;
	
	СписокВыбораПутей = Элементы.ПрограммыLinuxПутьКПрограмме.СписокВыбора;
	СписокВыбораПутей.Очистить();
	Если ЗначениеЗаполнено(ПутьПоУмолчанию) Тогда
		Если ОбщегоНазначенияКлиент.ЭтоLinuxКлиент() Тогда
			СписокВыбораПутей.Добавить("ПутьLinux", НСтр("ru = 'Стандартный путь для Linux'"));
		Иначе
			СписокВыбораПутей.Добавить("ПутьMac", НСтр("ru = 'Стандартный путь для Mac OS'"));
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриИзмененииСоставаИлиНастроекПрограмм()
	
	ЗаполнитьПрограммыИНастройки();
	
	ОпределитьУстановленныеПрограммы();
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеПроверкиПрограммКриптографии(Результат, Оповещение) Экспорт
	
	Если Не Результат.ПроверкаВыполнена Тогда
		Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Истина;
		Элементы.ДекорацияПроверкаУстановкиКриптопровайдера.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
			НСтр("ru = '<a href = ""%1"">Нажмите здесь</a>, чтобы увидеть все установленные на компьютере программы для работы с электронной подписью.'"),
			"ПроверитьУстановкуПрограммКриптографии");
	// Локализация
	ИначеЕсли Результат.ВозможенКонфликт Тогда
		
		МассивПрограмм = Новый Массив;
		Для Каждого Программа Из Результат.Программы Цикл
			Если ЗначениеЗаполнено(Программа.Программа)
				И МассивПрограмм.Найти(Программа.Программа) = Неопределено Тогда
				МассивПрограмм.Добавить(Программа.Программа);
			КонецЕсли;
		КонецЦикла;
		
		Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Истина;
		Элементы.ДекорацияПроверкаУстановкиКриптопровайдера.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
			НСтр("ru = 'На вашем компьютере установлено несколько программ с алгоритмами ГОСТ: %1.
				|Возможна некорректная работа из-за конфликта между ними. В этом случае программы следует удалить и после перезагрузки установить одну из них.'"),
				СтрСоединить(МассивПрограмм, ", "));
	// Конец Локализация
	Иначе
		Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Ложь;
	КонецЕсли;
		
	Если Результат.ПроверкаВыполнена Тогда
		
		Для Каждого Криптопровайдер Из Результат.Программы Цикл
			
			// Локализация
			Если ЗначениеЗаполнено(Криптопровайдер.Программа) И Не ЕстьПроверяемыеПрограммы Тогда
				ЕстьПроверяемыеПрограммы = Истина;
			КонецЕсли;
			// Конец Локализация
			
			Найдено = Программы.НайтиСтроки(Новый Структура("ИмяПрограммы, ТипПрограммы",
				Криптопровайдер.ИмяПрограммы, Криптопровайдер.ТипПрограммы));
			
			Если Найдено.Количество() = 0
				Или ЭлектроннаяПодписьСлужебныйКлиентСервер.ИспользуютсяАвтоматическиеНастройки(Найдено[0].РежимИспользования) Тогда
				
				Если Найдено.Количество() = 0 Тогда 
					НоваяСтрока = Программы.Добавить();
				Иначе
					НоваяСтрока = Найдено[0];
				КонецЕсли;
				
				ЗаполнитьЗначенияСвойств(НоваяСтрока, Криптопровайдер,, "Ссылка, ПутьКПрограммеНаСервереАвто");
				НоваяСтрока.LinuxПутьКПрограмме = НоваяСтрока.ПутьКПрограммеАвто;
				НоваяСтрока.ТипРазмещения = 1;
				НоваяСтрока.Автоопределение = Истина;
				НоваяСтрока.РежимИспользованияКартинка = -1;
				НоваяСтрока.Наименование = Криптопровайдер.Представление;
			КонецЕсли;
			
		КонецЦикла;
		
		// Локализация
		Если Не ЕстьПроверяемыеПрограммы Тогда
			Элементы.ГруппаПодсказкаКриптопровайдеры.Видимость = Истина;
			Элементы.ДекорацияПроверкаУстановкиКриптопровайдера.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(
				НСтр("ru = 'Если планируется работа с усиленной квалифицированной электронной подписью, то на компьютере должна быть установлена сертифицированная программа (средство криптографической защиты информации).
					|<a href = ""%1"">Установить.</a>'"), "ПроверитьУстановкуПрограммКриптографии");
		КонецЕсли;
		// Конец Локализация
	КонецЕсли;
	
	Если Оповещение <> Неопределено Тогда
		ВыполнитьОбработкуОповещения(Оповещение);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПрограммыИНастройки(ОбновитьПовтИсп = Ложь)
	
	Если ОбновитьПовтИсп Тогда
		ОбновитьПовторноИспользуемыеЗначения();
	КонецЕсли;
	
	ПерсональныеНастройки = ЭлектроннаяПодпись.ПерсональныеНастройки();
	
	ДействияПриСохраненииСЭП                   = ПерсональныеНастройки.ДействияПриСохраненииСЭП;
	РасширениеДляЗашифрованныхФайлов           = ПерсональныеНастройки.РасширениеДляЗашифрованныхФайлов;
	РасширениеДляФайловПодписи                 = ПерсональныеНастройки.РасширениеДляФайловПодписи;
	ПутиКПрограммам                            = ПерсональныеНастройки.ПутиКПрограммамЭлектроннойПодписиИШифрования;
	СохранятьСертификатВместеСПодписью         = ПерсональныеНастройки.СохранятьСертификатВместеСПодписью;
	ЕстьПрограммыНаСервере                     = Ложь;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Программы.Ссылка,
	|	Программы.Наименование КАК Наименование,
	|	Программы.ИмяПрограммы,
	|	Программы.ТипПрограммы,
	|	Программы.АлгоритмПодписи,
	|	Программы.АлгоритмХеширования,
	|	Программы.АлгоритмШифрования,
	|	Программы.ПометкаУдаления КАК ПометкаУдаления,
	|	Программы.ЭтоВстроенныйКриптопровайдер,
	|	Программы.РежимИспользования,
	|	1 КАК ТипРазмещения
	|ИЗ
	|	Справочник.ПрограммыЭлектроннойПодписиИШифрования КАК Программы
	|ГДЕ
	|	НЕ Программы.ЭтоВстроенныйКриптопровайдер
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	Программы.Ссылка,
	|	Программы.Наименование,
	|	Программы.ИмяПрограммы,
	|	Программы.ТипПрограммы,
	|	Программы.АлгоритмПодписи,
	|	Программы.АлгоритмХеширования,
	|	Программы.АлгоритмШифрования,
	|	Программы.ПометкаУдаления,
	|	Программы.ЭтоВстроенныйКриптопровайдер,
	|	ЗНАЧЕНИЕ(Перечисление.РежимыИспользованияПрограммыЭлектроннойПодписи.Настроена),
	|	4
	|ИЗ
	|	Справочник.ПрограммыЭлектроннойПодписиИШифрования КАК Программы
	|ГДЕ
	|	Программы.ЭтоВстроенныйКриптопровайдер
	|	И &ИспользоватьЭлектроннуюПодписьВМоделиСервиса
	|
	|УПОРЯДОЧИТЬ ПО
	|	Наименование";
	
	Запрос.УстановитьПараметр("ИспользоватьЭлектроннуюПодписьВМоделиСервиса", 
		ЭлектроннаяПодписьСлужебный.ИспользоватьЭлектроннуюПодписьВМоделиСервиса());
	
	ТаблицаВыборки = Запрос.Выполнить().Выгрузить();
	
	Если ЭлектроннаяПодписьСлужебный.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSСлужебный = ОбщегоНазначения.ОбщийМодуль("СервисКриптографииDSSСлужебный");
		МодульСервисКриптографииDSSСлужебный.ДополнитьВыборкуПрограмм(ТаблицаВыборки);
	КонецЕсли;
	
	ТаблицаВыборки.Колонки.Добавить("ПутьКПрограммеНаСервереАвто", Новый ОписаниеТипов("Строка"));
	ТаблицаВыборки.Колонки.Добавить("РезультатПроверкиНаСервере", Новый ОписаниеТипов("Строка"));
	ТаблицаВыборки.Колонки.Добавить("Автоопределение", Новый ОписаниеТипов("Булево"));
	
	Настройки = ЭлектроннаяПодпись.ОбщиеНастройки();
	Если Настройки.ПроверятьЭлектронныеПодписиНаСервере Или Настройки.СоздаватьЭлектронныеПодписиНаСервере Тогда
		
		ПараметрыПроверки = Новый Структура;
		ПараметрыПроверки.Вставить("РасширенноеОписание", Истина);
		РезультатКриптопровайдеры = ЭлектроннаяПодпись.ПроверитьУстановкуПрограммКриптографии(ПараметрыПроверки);
		
		Если РезультатКриптопровайдеры.ПроверкаВыполнена Тогда
			
			Для Каждого Криптопровайдер Из РезультатКриптопровайдеры.Программы Цикл
				
				Если ЗначениеЗаполнено(Криптопровайдер.Программа) И Не ЕстьПроверяемыеПрограммы Тогда
					ЕстьПроверяемыеПрограммы = Истина;
				КонецЕсли;
				
				Найдено = ТаблицаВыборки.НайтиСтроки(Новый Структура("ИмяПрограммы, ТипПрограммы",
					Криптопровайдер.ИмяПрограммы, Криптопровайдер.ТипПрограммы));
				
				Если Найдено.Количество() = 0
					Или ЭлектроннаяПодписьСлужебныйКлиентСервер.ИспользуютсяАвтоматическиеНастройки(Найдено[0].РежимИспользования) Тогда
					Если Найдено.Количество() = 0 Тогда 
						СтрокаВыборки = ТаблицаВыборки.Добавить();
					Иначе
						СтрокаВыборки = Найдено[0];
					КонецЕсли;
					ЗаполнитьЗначенияСвойств(СтрокаВыборки, Криптопровайдер,,"Ссылка");
					СтрокаВыборки.ТипРазмещения = 1;
					СтрокаВыборки.ПометкаУдаления = Ложь;
					СтрокаВыборки.ПутьКПрограммеНаСервереАвто = Криптопровайдер.ПутьКПрограммеНаСервереАвто;
					СтрокаВыборки.Наименование = Криптопровайдер.Представление;
					СтрокаВыборки.Автоопределение = Истина;
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЕсли;
		
		Элементы.ПрограммыРезультатПроверкиНаСервере.Видимость = ЭтоПолноправныйПользователь;
	Иначе
		Элементы.ПрограммыРезультатПроверкиНаСервере.Видимость = Ложь;
	КонецЕсли;
	
	ОбработанныеСтроки = Новый Соответствие;
	Индекс = 0;
	
	Для каждого СтрокаВыборки Из ТаблицаВыборки Цикл
		
		ПрограммаНеИспользуется = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПрограммаНеИспользуется(СтрокаВыборки.РежимИспользования);
		
		Если Не Пользователи.ЭтоПолноправныйПользователь() 
			И (ПрограммаНеИспользуется Или СтрокаВыборки.ПометкаУдаления) Тогда
			Продолжить;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(СтрокаВыборки.Ссылка) Тогда
			Строки = Программы.НайтиСтроки(Новый Структура("Ссылка", СтрокаВыборки.Ссылка));
		Иначе
			Строки = Программы.НайтиСтроки(Новый Структура("ИмяПрограммы, ТипПрограммы",
				СтрокаВыборки.ИмяПрограммы, СтрокаВыборки.ТипПрограммы));
		КонецЕсли;
		
		Если Строки.Количество() = 0 Тогда
			Если Программы.Количество()-1 < Индекс Тогда
				Строка = Программы.Добавить();
			Иначе
				Строка = Программы.Вставить(Индекс);
			КонецЕсли;
		Иначе
			Строка = Строки[0];
			ИндексСтроки = Программы.Индекс(Строка);
			Если ИндексСтроки <> Индекс Тогда
				Программы.Сдвинуть(ИндексСтроки, Индекс - ИндексСтроки);
			КонецЕсли;
		КонецЕсли;
		// Обновление только измененных значений, чтобы таблица формы не обновлялась лишний раз.
		ОбновитьЗначение(Строка.Ссылка,                       СтрокаВыборки.Ссылка);
		ОбновитьЗначение(Строка.ПометкаУдаления,              СтрокаВыборки.ПометкаУдаления);
		ОбновитьЗначение(Строка.Наименование,                 СтрокаВыборки.Наименование);
		ОбновитьЗначение(Строка.ИмяПрограммы,                 СтрокаВыборки.ИмяПрограммы);
		ОбновитьЗначение(Строка.ТипПрограммы,                 СтрокаВыборки.ТипПрограммы);
		ОбновитьЗначение(Строка.АлгоритмПодписи,              СтрокаВыборки.АлгоритмПодписи);
		ОбновитьЗначение(Строка.АлгоритмХеширования,          СтрокаВыборки.АлгоритмХеширования);
		ОбновитьЗначение(Строка.АлгоритмШифрования,           СтрокаВыборки.АлгоритмШифрования);
		ОбновитьЗначение(Строка.Автоопределение,              СтрокаВыборки.Автоопределение);
		ОбновитьЗначение(Строка.РежимИспользования,           СтрокаВыборки.РежимИспользования);
		ОбновитьЗначение(Строка.ПутьКПрограммеНаСервереАвто,  СтрокаВыборки.ПутьКПрограммеНаСервереАвто);
		ОбновитьЗначение(Строка.ЭтоВстроенныйКриптопровайдер, СтрокаВыборки.ЭтоВстроенныйКриптопровайдер);
		
		Если ПрограммаНеИспользуется И Не СтрокаВыборки.ПометкаУдаления Тогда
			ОбновитьЗначение(Строка.ТипРазмещения, 9);
		Иначе
			ОбновитьЗначение(Строка.ТипРазмещения, СтрокаВыборки.ТипРазмещения + ?(СтрокаВыборки.ПометкаУдаления, 4, 0));
		КонецЕсли;
		
		Если СтрокаВыборки.Автоопределение Тогда // установленный криптопровайдер
			ОбновитьЗначение(Строка.LinuxПутьКПрограмме, СтрокаВыборки.ПутьКПрограммеНаСервереАвто);
			ОбновитьЗначение(Строка.РежимИспользованияКартинка, -1);
		Иначе
			ОбновитьЗначение(Строка.LinuxПутьКПрограмме, ПутиКПрограммам.Получить(СтрокаВыборки.Ссылка));
			ОбновитьЗначение(Строка.РежимИспользованияКартинка, 0);
		КонецЕсли;
		
		Если Строка.ЭтоВстроенныйКриптопровайдер И Не Строка.ПометкаУдаления Тогда
			ОбновитьЗначение(Строка.РезультатПроверки, НСтр("ru = 'Доступен.'"));
			ОбновитьЗначение(Строка.Установлена, Истина);
		ИначеЕсли ЭлектроннаяПодписьСлужебныйКлиентСервер.РазмещениеСертификата(СтрокаВыборки.ТипРазмещения) = "ОблачнаяПодпись"
				И Не Строка.ПометкаУдаления Или СтрокаВыборки.ТипРазмещения = 5 Тогда
			ОбновитьЗначение(Строка.РезультатПроверки, НСтр("ru = 'Доступен.'"));
			ОбновитьЗначение(Строка.Установлена, Истина);
		ИначеЕсли Строка.ТипРазмещения = 1 И (Настройки.ПроверятьЭлектронныеПодписиНаСервере Или Настройки.СоздаватьЭлектронныеПодписиНаСервере) Тогда
			ПараметрыСоздания = ЭлектроннаяПодписьСлужебный.ПараметрыСозданияМенеджераКриптографии();
			ПараметрыСоздания.Автоопределение = Ложь;
			ОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеРасширенноеОписаниеПрограммы();
			ЗаполнитьЗначенияСвойств(ОписаниеПрограммы, Строка);
			ОписаниеПрограммы.Представление = Строка.Наименование;
			ПараметрыСоздания.Программа = ОписаниеПрограммы;
			ПараметрыСоздания.ОписаниеОшибки = Новый Структура;
			МенеджерКриптографии = ЭлектроннаяПодписьСлужебный.МенеджерКриптографии("", ПараметрыСоздания);
			Если МенеджерКриптографии = Неопределено Тогда
				ОбновитьЗначение(Строка.РезультатПроверкиНаСервере, ПараметрыСоздания.ОписаниеОшибки.ОписаниеОшибки);
				ОбновитьЗначение(Строка.УстановленаНаСервере, Ложь);
			Иначе
				ОбновитьЗначение(Строка.РезультатПроверкиНаСервере, НСтр("ru = 'Установлена на сервере.'"));
				ОбновитьЗначение(Строка.УстановленаНаСервере, Истина);
			КонецЕсли;
		КонецЕсли;
		
		ОбработанныеСтроки.Вставить(Строка, Истина);
		Индекс = Индекс + 1;
	КонецЦикла;
	
	Индекс = Программы.Количество()-1;
	Пока Индекс >=0 Цикл
		Строка = Программы.Получить(Индекс);
		Если ОбработанныеСтроки.Получить(Строка) = Неопределено Тогда
			Программы.Удалить(Индекс);
		КонецЕсли;
		Индекс = Индекс-1;
	КонецЦикла;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьЗначение(СтароеЗначение, НовоеЗначение)
	
	Если СтароеЗначение <> НовоеЗначение Тогда
		СтароеЗначение = НовоеЗначение;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьНастройки()
	
	СохраняемыеНастройки = Новый Структура;
	СохраняемыеНастройки.Вставить("ДействияПриСохраненииСЭП",                   ДействияПриСохраненииСЭП);
	СохраняемыеНастройки.Вставить("РасширениеДляЗашифрованныхФайлов",           РасширениеДляЗашифрованныхФайлов);
	СохраняемыеНастройки.Вставить("РасширениеДляФайловПодписи",                 РасширениеДляФайловПодписи);
	СохраняемыеНастройки.Вставить("СохранятьСертификатВместеСПодписью",         СохранятьСертификатВместеСПодписью);
	СохранитьНастройкиНаСервере(СохраняемыеНастройки);
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СохранитьНастройкиНаСервере(СохраняемыеНастройки)
	
	ПерсональныеНастройки = ЭлектроннаяПодпись.ПерсональныеНастройки();
	ЗаполнитьЗначенияСвойств(ПерсональныеНастройки, СохраняемыеНастройки);
	ЭлектроннаяПодписьСлужебный.СохранитьПерсональныеНастройки(ПерсональныеНастройки);
	
	// Требуется для обновления персональных настроек на клиенте.
	ОбновитьПовторноИспользуемыеЗначения();
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура СохранитьПутьLinuxНаСервере(Программа, ПутьLinux)
	
	ПерсональныеНастройки = ЭлектроннаяПодпись.ПерсональныеНастройки();
	ПерсональныеНастройки.ПутиКПрограммамЭлектроннойПодписиИШифрования.Вставить(Программа, ПутьLinux);
	ЭлектроннаяПодписьСлужебный.СохранитьПерсональныеНастройки(ПерсональныеНастройки);
	
	// Требуется для обновления персональных настроек на клиенте.
	ОбновитьПовторноИспользуемыеЗначения();
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьПутьКПрограмме()
	
	ТекущиеДанные = Элементы.Программы.ТекущиеДанные;
	Если БезПраваСохранениеДанныхПользователя Тогда
		ТекущиеДанные.LinuxПутьКПрограмме = LinuxПутьКТекущейПрограмме;
		ПоказатьПредупреждение(,
			НСтр("ru = 'Невозможно сохранить путь к программе. Отсутствует право сохранения данных.
			           |Обратитесь к администратору.'"));
	Иначе
		СохранитьПутьLinuxНаСервере(ТекущиеДанные.Ссылка, ТекущиеДанные.LinuxПутьКПрограмме);
		ОпределитьУстановленныеПрограммы();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьПодключитьСообщитьВерсиюКомпоненты(ПредложитьЗагрузить)
	
	ПараметрыПодключения = ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты();
	ПараметрыПодключения.ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Требуется установка компоненты %1'"), "ExtraCryptoAPI");
	ПараметрыПодключения.ПредложитьЗагрузить = ПредложитьЗагрузить;
	ПараметрыПодключения.ПредложитьУстановить = Истина;
	
	ОписаниеКомпоненты = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеКомпоненты();
	
	ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета(
		Новый ОписаниеОповещения("СообщитьРезультатПодключенияКомпоненты", ЭтотОбъект),
		ОписаниеКомпоненты.ИмяОбъекта,
		ОписаниеКомпоненты.ПолноеИмяМакета,
		ПараметрыПодключения);
		
КонецПроцедуры

&НаКлиенте
Процедура СообщитьРезультатПодключенияКомпоненты(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат.Подключено Тогда
		Попытка 
			ОповещениеПослеПолученияВерсии = Новый ОписаниеОповещения("СообщитьВерсиюКомпонентыПослеПодключения", ЭтотОбъект);
			Результат.ПодключаемыйМодуль.НачатьВызовПолучитьВерсию(ОповещениеПослеПолученияВерсии);
			Возврат;
		Исключение
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Не удалось определить версию компоненты.
				| %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
			ПоказатьПредупреждение(, ТекстОшибки);
		КонецПопытки;
	Иначе
		Если ПустаяСтрока(Результат.ОписаниеОшибки) Тогда 
			// Пользователь отказался от установки.
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Компонента %1 не установлена.'"), "ExtraCryptoAPI");
			ПоказатьПредупреждение(, ТекстОшибки);
		Иначе 
			// Установка не удалась, описание ошибки в Результат.ОписаниеОшибки.
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Компонента %1 не установлена (%2).'"), "ExtraCryptoAPI", Результат.ОписаниеОшибки);
			ПоказатьПредупреждение(, ТекстОшибки);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура СообщитьВерсиюКомпонентыПослеПодключения(Результат, Параметры, ДополнительныеПараметры) Экспорт
	
	ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Установлена компонента %1 версии %2.'"), "ExtraCryptoAPI", Результат);
	ПоказатьПредупреждение(, ТекстСообщения);
	ОбновитьПовторноИспользуемыеЗначения();
	ЭлектроннаяПодписьСлужебныйКлиент.ОчиститьКэшУстановленныхКриптопровайдеров();
	Оповестить("Установка_КомпонентаExtraCryptoAPI");
	
КонецПроцедуры

#КонецОбласти
